cmake_minimum_required(VERSION 3.12)
#project name
project(LibDL.core)

#include env settings
include(env_settings.cmake)

#set cmake policy
CMAKE_POLICY(SET CMP0078 OLD)
if (NOT ${CMAKE_VERSION} VERSION_LESS 3.14)
    CMAKE_POLICY(SET CMP0086 OLD)
endif ()

set(CMAKE_BUILD_TYPE_KNOWN FALSE)
if (${CMAKE_BUILD_TYPE_KNOWN})
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build.")
else (${CMAKE_BUILD_TYPE_KNOWN})
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
endif ()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Release")


#include swig module
include(UseJava)
include(UseSWIG)

#set cmake property
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_JNI_TARGET TRUE)
set(CMAKE_SWIG_FLAGS -package LibDL.core)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing -Wno-unused-variable -Wno-deprecated-copy -Wno-parentheses -Wno-deprecated-declarations")

#find needed package
find_package(SWIG REQUIRED)
find_package(Boost REQUIRED COMPONENTS system filesystem serialization)
find_package(JNI REQUIRED)
find_package(Torch REQUIRED)
find_package(OpenMP)
find_package(CUDA)

#set output dir
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../target)

#set OpenMP variables
if (OPENMP_FOUND)
    message(STATUS "OPENMP FOUND")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
    set(CMAKE_SHARE_LINKER_FLAGS "${CMAKE_SHARE_LINKER_FLAGS} ${OpenMP_SHARE_LINKER_FLAGS}")
endif ()

#set libtorch version compatibility
if (${Torch_VERSION} VERSION_LESS "1.3.0")
    add_compile_definitions(Torch_Version_Less_13)
    message("Set Torch_Version_Less_13")
endif ()
if (${Torch_VERSION} VERSION_LESS "1.4.0")
    add_compile_definitions(Torch_Version_Less_14)
    message("Set Torch_Version_Less_14")
endif ()
if (${Torch_VERSION} VERSION_LESS "1.5.0")
    add_compile_definitions(Torch_Version_Less_15)
    message("Set Torch_Version_15")
endif ()

#set JNI_PATH
if (NOT JNI_FOUND)
    SET(JAVA_INCLUDE_PATH ${JAVA_PATH}/include)
    if (WIN32)
        SET(JAVA_INCLUDE_PATH2 ${JAVA_PATH}/include/win32)
    else ()
        SET(JAVA_INCLUDE_PATH2 ${JAVA_PATH}/include/linux)
    endif ()
endif ()

#include source files
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${JAVA_INCLUDE_PATH})
include_directories(${JAVA_INCLUDE_PATH2})

#add swig source file
file(
        GLOB_RECURSE
        i
        RELATIVE
        ${CMAKE_SOURCE_DIR}
        "${CMAKE_SOURCE_DIR}/LibDL/*.i"
)
set_property(SOURCE ${i} PROPERTY CPLUSPLUS ON)

#add cpp source file
file(
        GLOB_RECURSE
        cpp
        RELATIVE
        ${CMAKE_SOURCE_DIR}
        "${CMAKE_SOURCE_DIR}/LibDL/*.cpp"
)

#set all source files
SET(src ${i} ${cpp})

#add swig library
swig_add_library(
        LibDL.core
        LANGUAGE java
        OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../java/core/src/main/java/LibDL/core
        SOURCES ${src}
)

#link needed library
SWIG_LINK_LIBRARIES(LibDL.core "${TORCH_LIBRARIES}" "${Boost_LIBRARIES}")

#set compile property
set_property(TARGET LibDL.core PROPERTY CXX_STANDARD 14)
if (WIN32)
    set_property(TARGET LibDL.core PROPERTY SWIG_FLAGS "-D__WIN32__")
else ()
    set_property(TARGET LibDL.core PROPERTY SWIG_FLAGS "-D__linux__")
endif ()

#copy dlls if compiler is MSVC
if (MSVC)
    file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll")
    add_custom_command(TARGET LibDL.core
            POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different
            ${TORCH_DLLS}
            $<TARGET_FILE_DIR:LibDL.core>)
endif (MSVC)